From 908455aa41424aefbb328fd8c826be2e2b344ce6 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Tue, 24 Nov 2015 14:11:48 -0600
Subject: [PATCH 11/45] cpu/amd/family_10h-family_15h: Move CBMEM storage out
 of CC6 save region

The existing CBMEM TOM calculations did not account for the CC6 save region
(when enabled); this resulted in CBMEM storage being placed on top of the
CC6 save region, which resulted in corrupt CBMEM data and a boot hang.

Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/cpu/amd/family_10h-family_15h/ram_calc.c | 51 +++++++++++++++++++++++++++-
 src/cpu/amd/family_10h-family_15h/ram_calc.h |  1 +
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.c b/src/cpu/amd/family_10h-family_15h/ram_calc.c
index 9ac2c99..4fe997e 100644
--- a/src/cpu/amd/family_10h-family_15h/ram_calc.c
+++ b/src/cpu/amd/family_10h-family_15h/ram_calc.c
@@ -18,11 +18,30 @@
 #include <cpu/x86/msr.h>
 #include <cpu/amd/mtrr.h>
 
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+
 #include <cbmem.h>
 
 #include "ram_calc.h"
 
 #if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
+static inline uint8_t is_fam15h(void)
+{
+	uint8_t fam15h = 0;
+	uint32_t family;
+
+	family = cpuid_eax(0x80000001);
+	family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
+
+	if (family >= 0x6f)
+		/* Family 15h or later */
+		fam15h = 1;
+
+	return fam15h;
+}
+
 uint64_t get_uma_memory_size(uint64_t topmem)
 {
 	uint64_t uma_size = 0;
@@ -41,10 +60,40 @@ uint64_t get_uma_memory_size(uint64_t topmem)
 	return uma_size;
 }
 
+uint64_t get_cc6_memory_size()
+{
+	uint8_t enable_cc6;
+
+	uint64_t cc6_size = 0;
+
+	if (is_fam15h()) {
+		enable_cc6 = 0;
+
+#ifdef __PRE_RAM__
+		if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18))
+			enable_cc6 = 1;
+#else
+		device_t dct_dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+		if (pci_read_config32(dct_dev, 0x118) & (0x1 << 18))
+			enable_cc6 = 1;
+#endif
+
+		if (enable_cc6) {
+			/* Preserve the maximum possible CC6 save region
+			 * This needs to be kept in sync with
+			 * amdfam10_domain_read_resources() in northbridge.c
+			 */
+			cc6_size = 0x8000000;
+		}
+	}
+
+	return cc6_size;
+}
+
 void *cbmem_top(void)
 {
 	uint32_t topmem = rdmsr(TOP_MEM).lo;
 
-	return (void *) topmem - get_uma_memory_size(topmem);
+	return (void *) topmem - get_uma_memory_size(topmem) - get_cc6_memory_size();
 }
 #endif
diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.h b/src/cpu/amd/family_10h-family_15h/ram_calc.h
index 8cfc199..0bb4cac 100644
--- a/src/cpu/amd/family_10h-family_15h/ram_calc.h
+++ b/src/cpu/amd/family_10h-family_15h/ram_calc.h
@@ -17,5 +17,6 @@
 #define _AMD_MODEL_10XXX_RAM_CALC_H_
 
 uint64_t get_uma_memory_size(uint64_t topmem);
+uint64_t get_cc6_memory_size(void);
 
 #endif
-- 
2.1.4

